package com.myvision.view;

import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.acegisecurity.Authentication;
import org.acegisecurity.AuthenticationManager;
import org.acegisecurity.BadCredentialsException;
import org.acegisecurity.context.HttpSessionContextIntegrationFilter;
import org.acegisecurity.context.SecurityContext;
import org.acegisecurity.context.SecurityContextHolder;
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
import org.acegisecurity.ui.WebAuthenticationDetails;
import org.acegisecurity.ui.webapp.AuthenticationProcessingFilter;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class LoginForm {

	private Log log = LogFactory.getLog(LoginForm.class);

	private String username;

	private String password;

	private String message;

	private AuthenticationManager _authenticationManager;

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String getMessage() {
		return message;
	}

	public void setMessage(String message) {
		this.message = message;
	}

	public String doLoginAction() {
		String outcome = "failure";

		try {
			final String userName = getUsername();
			final String password = getPassword();

			final UsernamePasswordAuthenticationToken authReq = new UsernamePasswordAuthenticationToken(
					userName, password);

			final HttpServletRequest request = getRequest();
			authReq.setDetails(new WebAuthenticationDetails(request));

			final HttpSession session = request.getSession();
			session
					.setAttribute(
							AuthenticationProcessingFilter.ACEGI_SECURITY_LAST_USERNAME_KEY,
							userName);

			/*
			 * perform authentication
			 */
			final Authentication auth = getAuthenticationManager()
					.authenticate(authReq);

			/*
			 * initialize the security context.
			 */
			final SecurityContext secCtx = SecurityContextHolder.getContext();
			secCtx.setAuthentication(auth);
			session
					.setAttribute(
							HttpSessionContextIntegrationFilter.ACEGI_SECURITY_CONTEXT_KEY,
							secCtx);

			outcome = "success";

		} catch (BadCredentialsException e) {
			FacesContext
					.getCurrentInstance()
					.addMessage(
							null,
							new FacesMessage(
									"Username or password incorrect, please try again."));
		} catch (Exception e) {
			if (log.isDebugEnabled()) {
				log.debug(e);
			}
			FacesContext.getCurrentInstance().addMessage(null,
					new FacesMessage(e.getMessage()));
		}

		if (log.isDebugEnabled()) {
			log.debug(">>> " + getUsername() + " login the platform " + outcome);
		}

		return outcome;
	}

	public void logout(ActionEvent e) {

		final HttpServletRequest request = getRequest();
		request.getSession(false).removeAttribute(
				HttpSessionContextIntegrationFilter.ACEGI_SECURITY_CONTEXT_KEY);

		/*
		 * simulate the SecurityContextLogoutHandler
		 */
		SecurityContextHolder.clearContext();

		request.getSession(false).invalidate();
		if (log.isDebugEnabled()) {
			log.debug(">>> " + getUsername() + " logout");
		}
	}

	private HttpServletRequest getRequest() {
		return (HttpServletRequest) FacesContext.getCurrentInstance()
				.getExternalContext().getRequest();
	}

	public AuthenticationManager getAuthenticationManager() {
		return _authenticationManager;
	}

	public void setAuthenticationManager(
			AuthenticationManager authenticationManager) {
		_authenticationManager = authenticationManager;
	}

}
